using Microsoft.Extensions.Options;

namespace Crux.Core.EasyNetQ;
/// <summary>
/// RabbitMqBusAccessor
/// </summary>
public class RabbitMqBusAccessor(IOptions<EasyNetQOption> options)
    : IRabbitMqBusAccessor
{

    #region private fields
    private IBus? bus;
    private int _location = 0;
    private readonly EasyNetQOption option = options.Value;
    #endregion  private fields
    #region implements IRabbitMqBusAccessor
    /// <summary>
    /// 获取IBus对象
    /// </summary>
    /// <see cref="IRabbitMqBusAccessor"/>
    /// <returns>IBus</returns>
    public IBus TryGetBus()
    {
        if (bus is not null)
        {
            return bus;
        }

        while (true)
        {
            if (0 != Interlocked.CompareExchange(ref _location, 1, 0))
            {
                if (bus is not null)
                {
                    return bus;
                }

                Thread.Sleep(1);

                continue;
            }

            try
            {
                if (bus is not null)
                {
                    return bus;
                }

                return Initialize(option);
            }
            finally
            {
                Interlocked.Exchange(ref _location, 0);
            }
        }
    }

    private IBus Initialize(EasyNetQOption option)
    {
        option.RegisterServices ??= new Action<IServiceRegister>(p => { });

        RabbitHutch.RegisterBus(option.ServiceRegister, (p) => option.ConnectionConfiguration, option.RegisterServices);

        return bus = RabbitHutch.CreateBus(option.ConnectionConfiguration, option.RegisterServices);
    }
    #endregion implements IRabbitMqBusAccessor
}